//
// Created by fazhehy on 2024/3/22.
//

#include "protocol.h"

struct Remote remote;

void protocol_init()
{
    remote.transmitBuffer = transmit_buffer;
    remote.receiveBuffer = receive_buffer;
    remote.transmitBufferLen = 0;
    remote.medAdcValue1 = 0;
    remote.medAdcValue2 = 0;
    remote.protocolState = 0;
}

void protocol_send_command(uint8_t keyNum, uint16_t adcValue1, uint16_t adcValue2)
{
    if (remote.transmitBufferLen == 0){
        memset(remote.transmitBuffer, 0, 32);
        remote.transmitBuffer[0] = 'C';
        remote.transmitBuffer[2] = keyNum;
        remote.transmitBuffer[3] = (adcValue1 >> 8)&0xff;
        remote.transmitBuffer[4] = (adcValue1)&0xff;
        remote.transmitBuffer[5] = (remote.medAdcValue1 >> 8)&0xff;
        remote.transmitBuffer[6] = (remote.medAdcValue1)&0xff;
        remote.transmitBuffer[7] = (adcValue2 >> 8)&0xff;
        remote.transmitBuffer[8] = (adcValue2)&0xff;
        remote.transmitBuffer[9] = (remote.medAdcValue2 >> 8)&0xff;
        remote.transmitBuffer[10] =(remote.medAdcValue2)&0xff;
        remote.transmitBufferLen = 11;
        remote.transmitBuffer[1] = remote.transmitBufferLen;
    }
}

// non-block
void protocol_send_data(const uint8_t * buf, uint8_t len)
{
    static uint8_t temp_buffer[255];
    static uint8_t waitSendLen = 0, index = 0;
    // check send
    if (waitSendLen == 0){
        memset(temp_buffer, 0, len);
        waitSendLen = len;
        index = 0;
        if (len > 250)
            return;
        // copy buffer
        for (int i = 0; i < len; ++i) {
            temp_buffer[i] = buf[i];
        }
    }
    else{
        // send data
        // no loop
        // copy to transmitBuffer
        if (remote.transmitBufferLen == 0){
//            memset(remote.transmitBuffer, 0, 32);
            remote.transmitBuffer[0] = 'D';
            if (waitSendLen >= 30){
                remote.transmitBuffer[1] = 30;
                for (int i = 0; i < 30; ++i) {
                    remote.transmitBuffer[i+2] = temp_buffer[i+index];
                }
                waitSendLen -= 30;
                index += 30;
            }
            else{
                remote.transmitBuffer[1] = waitSendLen;
                for (int i = 0; i < waitSendLen; ++i) {
                    remote.transmitBuffer[i+2] = temp_buffer[i+index];
                }
                index += waitSendLen;
                waitSendLen = 0;
            }
            // start send
            remote.transmitBufferLen = 1;
        }
    }
}

uint8_t protocol_printf(const char * format, ...)
{
    char loc_buf[128];
    char * temp = loc_buf;
    va_list arg;
    va_list copy;
    va_start(arg, format);
    va_copy(copy, arg);
    int len = vsnprintf(temp, sizeof(loc_buf), format, copy);
    va_end(copy);
    if(len < 0) {
        va_end(arg);
        return 0;
    }
    va_end(arg);
    protocol_send_data((uint8_t *)temp, strlen(temp));
    return len;
}

void protocol_analysis()
{
    if (remote.protocolState == 0){
        remote.protocolState = 1;
        switch (remote.receiveBuffer[0]) {
            case 'D': // data
                remote.protocolType = 'D';
                remote.receiveBufferLen = remote.receiveBuffer[1];
                break;
            case 'C':// command
                remote.protocolType = 'C';
                remote.operation = remote.receiveBuffer[2];
                remote.adcValue1 = (remote.receiveBuffer[3] << 8) | (remote.receiveBuffer[4]);
                remote.medAdcValue1 = (remote.receiveBuffer[5]<<8)|(remote.receiveBuffer[6]);
                remote.adcValue2 = (remote.receiveBuffer[7] << 8) | (remote.receiveBuffer[8]);
                remote.medAdcValue2 = (remote.receiveBuffer[9]<<8)|(remote.receiveBuffer[10]);
                break;
            default:
                break;
        }
    }
}

